package com.nettyPractice;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

/**
 * ChannelInboundHandlerAdapter 是 Netty 提供的一个抽象类
 * 用于处理入站（从客户端到服务端）的 I/O 事件。通过继承它，我们可以重写相关方法来处理具体的业务逻辑。
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    private static final Logger logger = Logger.getLogger(NettyServerHandler.class.getName());
    private static final AtomicInteger atomicInteger = new AtomicInteger(1);

    @Override
    // ChannelHandlerContext 是一个非常重要的对象，它代表了 ChannelHandler 和 ChannelPipeline 之间的关联。
    // 通过 ctx 可以获取 Channel 对象、向通道中写入数据、触发事件等。
    // Object msg：表示接收到的客户端消息，在 Netty 中，数据是以对象的形式传递的。
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        try {
            RpcRequest rpcRequest = (RpcRequest) msg;
            logger.info("接收到客户端消息：" + rpcRequest);
            RpcResponse messageFromServer = RpcResponse.builder().message("message from server").build();
            // 通过 ChannelHandlerContext 对象将 RpcResponse 对象写入通道并刷新缓冲区，确保数据发送到客户端。
            // writeAndFlush 方法返回一个 ChannelFuture 对象，它表示异步操作的结果。可以通过 ChannelFuture 来监听操作是否完成、成功或失败。
            ChannelFuture future = ctx.writeAndFlush(messageFromServer);
             //  ChannelFuture 对象添加一个监听器，当异步操作完成时，监听器会被触发。
            // ChannelFutureListener.CLOSE：表示当操作完成后，关闭当前的通道。
            future.addListener(ChannelFutureListener.CLOSE);
        }finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.info("server catch exception : " + cause.getMessage());
        ctx.close();
    }
}
